猜数字
- 猜数字 这个项目非常简单,它涉及到随机数的生成和用户输入操作。 我们使用了 bufio 库来处理输入数据。
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
2
简单字典
- 标准库 strconv 它主要用于字符和其他类型之间的转换。
strconv.Atoi(s string) int
- 标准库 strings
strings.TrimSuffix(s string , suffix string) string
删除末尾字符,如果没有就正常返回
- 网络库
client := &http.Client{}
初始化请求客户端
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)
构造头
req.Header.Set("authority", "api.interpreter.caiyunai.com")
请求
bodyText, err := io.ReadAll(resp.Body)
err = json.Unmarshal(bodyText, &dictResponse)
2
- os 库
word := os.Args[1]
获取环境参数
socks5 代理
package main
import (
"context"
"encoding/binary"
"fmt"
"io"
"net"
)
const (
socks5Ver = 0x05
atypeIPV4 = 0x01
atypeHOST = 0x03
cmdConnect = 0x01
)
func main() {
// 假设在这里建立一个 net.Listener 监听 Socks5 代理请求
for {
client, err := acceptConnection()
if err != nil {
continue
}
// 开启一个 goroutine 处理客户端请求
go handleSocks5Client(client)
}
}
func acceptConnection() (net.Conn, error) {
// 实现接收连接请求的逻辑
}
func handleSocks5Client(conn net.Conn) {
defer conn.Close()
// 鉴权阶段
if err := auth(conn); err != nil {
fmt.Println("Authentication error:", err)
return
}
// 通讯阶段
addr, err := connect(conn)
if err != nil {
fmt.Println("Connection error:", err)
return
}
// 给客户端回包,表示连接成功
_, _ = conn.Write([]byte{socks5Ver, 0x00, 0x00, atypeIPV4, 0, 0, 0, 0, 0, 0})
// 开始进行数据转发
dest, err := net.Dial("tcp", addr)
if err != nil {
fmt.Println("Failed to connect to destination:", err)
return
}
defer dest.Close()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 从客户端到目标地址的数据拷贝
go func() {
_, _ = io.Copy(dest, conn)
cancel()
}()
// 从目标地址到客户端的数据拷贝
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
}
func auth(conn net.Conn) error {
buf := make([]byte, 2)
_, err := io.ReadFull(conn, buf)
if err != nil {
return err
}
ver, nmethods := buf[0], buf[1]
methods := make([]byte, nmethods)
_, err = io.ReadFull(conn, methods)
if err != nil {
return err
}
// 在这里根据收到的 methods 进行认证处理
// 假设这里选择不需要认证,回包告知客户端不需要认证
_, err = conn.Write([]byte{socks5Ver, 0x00})
if err != nil {
return err
}
return nil
}
func connect(conn net.Conn) (string, error) {
buf := make([]byte, 4)
_, err := io.ReadFull(conn, buf)
if err != nil {
return "", err
}
ver, cmd, _, atyp := buf[0], buf[1], buf[2], buf[3]
if ver != socks5Ver || cmd != cmdConnect {
return "", fmt.Errorf("Unsupported SOCKS5 command")
}
var addr string
switch atyp {
case atypeIPV4:
buf := make([]byte, 4)
_, err := io.ReadFull(conn, buf)
if err != nil {
return "", err
}
addr = fmt.Sprintf("%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3])
case atypeHOST:
hostSizeBuf := make([]byte, 1)
_, err := io.ReadFull(conn, hostSizeBuf)
if err != nil {
return "", err
}
hostSize := int(hostSizeBuf[0])
hostBuf := make([]byte, hostSize)
_, err = io.ReadFull(conn, hostBuf)
if err != nil {
return "", err
}
addr = string(hostBuf)
}
portBuf := make([]byte, 2)
_, err = io.ReadFull(conn, portBuf)
if err != nil {
return "", err
}
port := binary.BigEndian.Uint16(portBuf)
return fmt.Sprintf("%v:%v", addr, port), nil
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
使用 SOCKS5 代理的实现,涵盖了以下主要步骤:
鉴权阶段:
解析客户端发送的版本号、支持的认证方法数量和认证方法列表。 针对支持的认证方法进行验证,返回认证成功的回包。 通讯阶段:
解析客户端发送的连接请求,包括版本号、命令类型、目标地址类型、目标地址、目标端口等信息。 根据目标地址类型和地址解析方式,获取目标地址和端口号。 向目标地址发起连接请求,并返回连接成功的回包。 进程管理:
使用 goroutine 后台开启两个服务器交互进程。 通过 context 库进行进程管理,确保进程在必要时可以被关闭。 将客户端和目标之间的数据互相拷贝,使得数据能够在两者之间传递。
四、课后个人总结:
在这节课学习的内容中,我收获了很多关于 Go 语言编程的知识和技能。以下是我的感想:
Go 语言的简洁和高效:通过学习这些基础标准库和相关功能,我深刻感受到 Go 语言的简洁和高效。标准库提供了丰富的功能,让编程变得更加简单和高效。
数据类型转换和字符串处理:学习了 strconv 和 strings 包,对于数据类型转换和字符串处理有了更深入的了解。这些工具使得在处理用户输入和数据转换时更加方便。
网络编程和 HTTP 库:了解了 Go 语言中的网络编程和 net/http 包,我现在能够编写简单的 HTTP 服务器和客户端,这对于开发网络应用和服务端程序非常有用。
文件操作和系统交互:通过 os 包的学习,我学会了如何在 Go 语言中进行文件操作和与操作系统进行交互,这对于处理文件和系统配置十分重要。
代理和鉴权:学习了 socks5 代理和鉴权机制,我对网络代理和安全认证有了更深刻的理解,这对于开发安全性较高的应用非常重要。
上下文处理:context 包的学习使我了解了在 Go 语言中如何优雅地处理请求上下文,更好地控制请求的流程和生命周期。